/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * eqClassGUI.java
 *
 * Created on 26-nov-2010, 11.17.30
 */

package lolbatfsm.implementation.gui;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseEvent;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.swing.AbstractButton;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;
import lolbatfsm.system.EquivalenceClass;
import lolbatfsm.system.FSM;
import lolbatfsm.system.SynchronousTransition;
import lolbatfsm.system.Transition;

/**
 *  This class is a form which allow user to select and modify
 *  one equivalence class, and applies this changes in all the FSMs
 * @author Fabio Lola
 */
public class EqClassGUI extends javax.swing.JDialog {

    private Set<EquivalenceClass> equivalenceClassSet;
    private Set<FSM> fsmSet;
    private final Enumeration<AbstractButton> radioButtonList;
    Map<JRadioButton, Object> radioeqClasses;

    
    public static EqClassGUI createAndShow(Set<EquivalenceClass> equivalenceClassSet, HashSet<FSM> fsmSet) {
        EqClassGUI eqClassGUI = new EqClassGUI(equivalenceClassSet, fsmSet);
        eqClassGUI.setLocation(200, 100);
        eqClassGUI.setModal(true);
        eqClassGUI.setVisible(true);
        return eqClassGUI;
    }
    
    /** 
     *  @param equivalenceClassSet a set of all the equivalence classes
     *  @param fsmSet a set of all the FSM's
     */
    private EqClassGUI(Set<EquivalenceClass> equivalenceClassSet, Set<FSM> fsmSet) {
        initComponents();
        this.equivalenceClassSet = equivalenceClassSet;
        this.fsmSet = fsmSet;
        radioeqClasses = new HashMap<JRadioButton, Object>();
        ButtonGroup eqClassGroup = new ButtonGroup();
        for(EquivalenceClass equivalenceClass : equivalenceClassSet){
            JRadioButton button = new JRadioButton(equivalenceClass.getName());
            button.setName(equivalenceClass.getName());
            eqClassGroup.add(button);
            radioeqClasses.put(button, equivalenceClass);
        }
        GridBagConstraints c = new GridBagConstraints();
        GridBagLayout gridBagLayout = new GridBagLayout();
        panel.setLayout(gridBagLayout);
        c.gridx = 0;
        c.gridy = 0;
        c.anchor = GridBagConstraints.NORTHWEST;
        c.weightx = 0.5;
        c.weighty = 0.1;
        c.insets = new Insets(5, 5, 5, 0);
        panel.add(new JLabel("Select Equivalence class you want to modify, then click Ok"), c);
        c.gridy++;
        radioButtonList = eqClassGroup.getElements();
        while(radioButtonList.hasMoreElements()){
            JRadioButton button = (JRadioButton) radioButtonList.nextElement();
            panel.add(button, c);
            c.gridx++;
            Integer duration = ((EquivalenceClass) radioeqClasses.get(button)).getDuration();
            panel.add(new JLabel("duration:   " + Integer.toString(duration)), c);
            c.gridx=0;
            c.gridy++;
        }
        c.gridy++;
        c.weighty = 1.0;
        panel.add(Box.createVerticalGlue(), c);
        this.pack();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        cancelButton = new javax.swing.JButton();
        okButton = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        panel = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setResizable(false);

        cancelButton.setText("Cancel");
        cancelButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                cancelButtonMouseClicked(evt);
            }
        });

        okButton.setText("Ok");
        okButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                okButtonMouseClicked(evt);
            }
        });

        panel.setName("panel"); // NOI18N
        panel.setLayout(new java.awt.GridBagLayout());
        jScrollPane1.setViewportView(panel);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 62, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(cancelButton))
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 452, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 270, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cancelButton)
                    .addComponent(okButton))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void cancelButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_cancelButtonMouseClicked
        this.setVisible(false);
    }//GEN-LAST:event_cancelButtonMouseClicked

    private void okButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_okButtonMouseClicked
        EquivalenceClass equivalenceClass = null;
        EquivalenceClass oldEquivalenceClass = null;
        Set<FSM> oldFSM = new HashSet();
        Set<FSM> newFSM = new HashSet();
        for (Entry<JRadioButton, Object> entry : radioeqClasses.entrySet()) {
            JRadioButton nextButton = entry.getKey();
            if(nextButton.isSelected()){
                oldEquivalenceClass = (EquivalenceClass) entry.getValue();
                boolean exist = false;
                String eqClassName = null;
                Integer durationEqClass = null;
                do {
                    exist = false;
                    eqClassName = JOptionPane.showInputDialog("Equivalence Class name", nextButton.getText());
                    for (EquivalenceClass _equivalenceClass : equivalenceClassSet) {
                        if (_equivalenceClass.getName().equals(eqClassName) && !nextButton.getText().equals(eqClassName)) {
                            exist = true;
                        }
                    }
                    if (exist) {
                        JOptionPane.showMessageDialog(null, eqClassName + " already exists, choose another name", "ERROR", JOptionPane.ERROR_MESSAGE);
                    } else if (eqClassName != null && ((eqClassName.equals("") || eqClassName.matches(" *")) || eqClassName.equals("Add new"))) {
                        JOptionPane.showMessageDialog(null, "Void String, please re-type Equivalence Class name", "ERROR", JOptionPane.ERROR_MESSAGE);
                        exist = true;
                    }
                } while (exist);
                if(eqClassName != null){
                    Boolean intError = false;
                    do {
                        intError = false;
                        try {
                            durationEqClass = Integer.parseInt(JOptionPane.showInputDialog("Duration",
                                    ((EquivalenceClass) entry.getValue()).getDuration()));
                            if(durationEqClass == 0){
                                JOptionPane.showMessageDialog(null, "Invalid duration (0 or null), please re-type duration", "ERROR", JOptionPane.ERROR_MESSAGE);
                                intError = true;
                            }
                        } catch (NumberFormatException exception) {
                            if (durationEqClass != null) {
                                JOptionPane.showMessageDialog(null, "Invalid duration (0 or null), please re-type duration", "ERROR", JOptionPane.ERROR_MESSAGE);
                                intError = true;
                            }
                        }
                    } while (intError);
                    if (durationEqClass != null) {
                        nextButton.setText(eqClassName);
                        equivalenceClass = new EquivalenceClass(eqClassName, durationEqClass);
                        entry.setValue(equivalenceClass);
                        equivalenceClassSet.remove(oldEquivalenceClass);
                        equivalenceClassSet.add(equivalenceClass);                        
                        if(equivalenceClass != null){
                            for(FSM fsm:fsmSet){
                                Transition[] transitions = new Transition[fsm.getTransitions().size()];
                                fsm.getTransitions().toArray(transitions);
                                for(int i=0; i<transitions.length; i++){
                                    if(transitions[i] instanceof SynchronousTransition){
                                        if(((SynchronousTransition) transitions[i]).getEquivalenceClass().equals(oldEquivalenceClass)){
                                            Transition tempTransition = transitions[i];
                                            transitions[i] = new SynchronousTransition(tempTransition.getSourceState(), tempTransition.getDestinationState(), equivalenceClass);
                                            oldFSM.add(fsm);
                                            newFSM.add(new FSM(fsm.getName(), fsm.getCurrentState(), transitions));
                                        }
                                    }
                                }
                            }
                            fsmSet.removeAll(oldFSM);
                            fsmSet.addAll(newFSM);
                        }
                    }
                }
            }
        }
        this.pack();
        this.setVisible(false);
    }//GEN-LAST:event_okButtonMouseClicked

    public void testOkButtonClick(){
        okButtonMouseClicked(new MouseEvent(cancelButton, 0, 0, 0, 0, 0, 1, false));
    }

    public void testCancelButtonClick(){
        cancelButtonMouseClicked(new MouseEvent(cancelButton, 0, 0, 0, 0, 0, 1, false));
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton cancelButton;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JButton okButton;
    private javax.swing.JPanel panel;
    // End of variables declaration//GEN-END:variables

}
